#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <LittleFS.h>
#include <Arduino.h>
#include <wifi_manager.h>
#include <ArduinoJson.h>
#include <map>
#include <Preferences.h>
#include <config.h>
#include <HaMqttEntities.h>
#include <mqtt_manager.h>
AsyncWebServer server(80);
std::map<AsyncWebServerRequest *, String> requestBodyMap;

void handleWifiState(AsyncWebServerRequest *request)
{
  String result = WiFi.status() == WL_CONNECTED ? "true" : "false";
  preferences.begin("wifi", true);
  String ssId = preferences.getString("ssid","");
  String pwd = preferences.getString("pwd","");
  preferences.end();
  String json = "{";
  json += "\"name\":\"" + ssId + "\",";
  json += "\"password\":\"" + pwd + "\",";
  json += "\"ip\":\"" + WiFi.localIP().toString() + "\",";
  json += "\"isConnected\":" + result;
  json += "}";

  request->send(200, "application/json", json);
}

void handleAPState(AsyncWebServerRequest *request)
{
  wifi_mode_t mode = WiFi.getMode();
   String result = "false";
  if (mode == WIFI_MODE_AP || mode == WIFI_MODE_APSTA) {
    result = "true";
  }

  preferences.begin("wifi", true);
  String ap_ssid = preferences.getString("ap_ssid","");
  String ap_password = preferences.getString("ap_password","");
  preferences.end();
  String json = "{";
  json += "\"name\":\"" + ap_ssid + "\",";
  json += "\"password\":\"" + ap_password + "\",";
  json += "\"isEnable\":" + result + ",";
  json += "\"ip\":\"" + WiFi.softAPIP().toString() + "\"";
  json += "}";

  request->send(200, "application/json", json);
}

void handleMqttState(AsyncWebServerRequest *request)
{
  String connected = HAMQTT.connected() ? "true" : "false";
  preferences.begin("mqtt", false);
  String mqttIp = preferences.getString("ip", "");
  int port = preferences.getInt("port", 1883);
  String clientId = preferences.getString("clientId", "");
  String username = preferences.getString("username", "");
  String password = preferences.getString("password", "");
  preferences.end();
  String json = "{";
  json += "\"ip\":\"" + mqttIp + "\",";
  json += "\"port\":\"" + String(port) + "\",";
  json += "\"clientId\":\"" + clientId + "\",";
  json += "\"username\":\"" + username + "\",";
  json += "\"password\":\"" + password + "\",";
  json += "\"connected\":" + connected;
  json += "}";

  request->send(200, "application/json", json);
}


void restartWifi(AsyncWebServerRequest *request)
{
  String json = "ok";
  request->send(200, "application/json", json);
  isWifiConnecting = false;
  isNeedWifiReconnect = true;
  Serial.print("已修改状态为true");Serial.println(isNeedWifiReconnect);
}

void switchAP(AsyncWebServerRequest *request)
{
  if (request->hasParam("enable")) {
    String enableValue = request->getParam("enable")->value();
    Serial.println("enable = " + enableValue);
    preferences.begin("wifi", false);
    preferences.putString("isEnable", enableValue);
    if (enableValue == "false") {
      Serial.println("关闭AP..........");
      WiFi.softAPdisconnect(true); 
    } else {
      Serial.println("打开AP..........");
      String ap_ssid = preferences.getString("ap_ssid","");
      String ap_password = preferences.getString("ap_password","");
      WiFi.mode(WIFI_AP_STA);
      WiFi.softAP(ap_ssid,ap_password);
    }
    preferences.end();
  }

  request->send(200, "application/json", "ok");
}

void restartMqtt(AsyncWebServerRequest *request)
{
  String json = "ok";
  request->send(200, "application/json", json);
  isNeedMQTTReconnect = true;
  Serial.print("MQTT重连，已修改状态为true");Serial.println(isNeedMQTTReconnect);
}

void handleWifiConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
  Serial.printf("infex: %u\n", index);
  if (index == 0)
  {
    requestBodyMap[request] = "";
  }
  requestBodyMap[request] += String((char *)data).substring(0, len);
  if (index + len == total)
  {
    String &fullBody = requestBodyMap[request];
    Serial.println("json数据: \n" + fullBody);
    // 1. 解析 JSON
    JsonDocument doc;
    DeserializationError error = deserializeJson(doc, fullBody);
    // 清理缓存
    requestBodyMap.erase(request);
    if (error)
    {
      request->send(400, "application/json", "false");
      return;
    }

    const char *newSsid = doc["name"];
    const char *newPassword = doc["password"];

    // 2. 更新全局变量
    preferences.begin("wifi", false); 
    preferences.putString("ssid", newSsid);
    preferences.putString("pwd", newPassword);
    preferences.end();
    Serial.printf("新SSID: %s, 新密码: %s\n", newSsid, newPassword);

    // 4. 响应前端
    request->send(200, "application/json", "true");
  }
}

void handleAPConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
  Serial.printf("infex: %u\n", index);
  if (index == 0)
  {
    requestBodyMap[request] = "";
  }
  requestBodyMap[request] += String((char *)data).substring(0, len);
  if (index + len == total)
  {
    String &fullBody = requestBodyMap[request];
    Serial.println("json数据: \n" + fullBody);
    // 1. 解析 JSON
    JsonDocument doc;
    DeserializationError error = deserializeJson(doc, fullBody);
    // 清理缓存
    requestBodyMap.erase(request);
    if (error)
    {
      request->send(400, "application/json", "false");
      return;
    }

    const char *newSsid = doc["name"];
    const char *newPassword = doc["password"];

    // 2. 更新全局变量
    preferences.begin("wifi", false); 
    preferences.putString("ap_ssid", newSsid);
    preferences.putString("ap_password", newPassword);
    preferences.end();
    Serial.printf("新APSSID: %s, 新AP密码: %s\n", newSsid, newPassword);

    // 4. 响应前端
    request->send(200, "application/json", "true");
  }
}

void handleMqttConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
{
  Serial.printf("infex: %u\n", index);
  if (index == 0)
  {
    requestBodyMap[request] = "";
  }
  requestBodyMap[request] += String((char *)data).substring(0, len);
  if (index + len == total)
  {
    String &fullBody = requestBodyMap[request];
    Serial.println("json数据: \n" + fullBody);
    // 1. 解析 JSON
    JsonDocument doc;
    DeserializationError error = deserializeJson(doc, fullBody);
    // 清理缓存
    requestBodyMap.erase(request);
    if (error)
    {
      request->send(400, "application/json", "false");
      return;
    }

    String ip = doc["ip"];
    int port = doc["port"];
    String clientId = doc["clientId"];
    String username = doc["username"];
    String password = doc["password"];
    Serial.println("准备连接 MQTT,IP:" + ip);
    Serial.println("准备连接 port:" + String(port));
    Serial.println("准备连接 MQT,clientId:" + clientId);
    Serial.println("准备连接 MQTT,username:" + username);
    Serial.println("准备连接 MQTT,password:" + password);
    // 2. 更新全局变量
    preferences.begin("mqtt", false); 
    preferences.putString("ip", ip);
    preferences.putInt("port", port);
    preferences.putString("clientId", clientId);
    preferences.putString("username", username);
    preferences.putString("password", password);
    preferences.end();

    // 3. 响应前端
    request->send(200, "application/json", "true");
  }
}


void webServerInit()
{
  if (!LittleFS.begin(true))
  {
    Serial.println("LittleFS 挂载失败");
    return;
  }

  // 静态文件配置
  server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html");

  // 处理 /wifi-state 请求
  server.on("/api/wifi-state", HTTP_GET, handleWifiState);
  server.on("/api/ap-state", HTTP_GET, handleAPState);
  server.on("/api/mqtt-state", HTTP_GET, handleMqttState);

  // 处理 /wifi-reconnect 请求
  server.on("/api/wifi-reconnect", HTTP_GET, restartWifi);
  server.on("/api/ap-switch", HTTP_GET, switchAP);
  server.on("/api/mqtt-reconnect", HTTP_GET, restartMqtt);

  // 修改wifi配置
  server.on("/api/wifi-config", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handleWifiConfig);
  server.on("/api/ap-config", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handleAPConfig);
  server.on("/api/mqtt-config", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handleMqttConfig);

  server.begin();
  Serial.println("Web服务器启动成功");
}
